﻿package com.tomvian.maths.areas
{
	import com.tomvian.maths.Vector2D;
	
	/**
	 * TorusSectorArea
	 * @author Thomas Vian
	 */
	public class TorusSectorArea extends Area
	{
		//--------------------------------------------------------------------------
		//
		//  Properties
		//
		//--------------------------------------------------------------------------
		
		private var _center:Vector2D;
		private var _innerRadius:Number;
		private var _outerRadius:Number;
		private var _innerRadiusSqr:Number;
		private var _outerRadiusSqr:Number;
		
		private var _radiusDiff:Number;
		
		private var _ratio:Number;
		private var _ratioGap:Number;
		
		private var _angleMin:Number;
		private var _angleMax:Number;
		private var _angleLeast:Number;
		private var _angleSpan:Number;
		
		private static const twoPi:Number = Math.PI * 2.0;
		
		//--------------------------------------------------------------------------
		//
		//  Constructor
		//
		//--------------------------------------------------------------------------
		
		public function TorusSectorArea(center:Vector2D, innerRadius:Number, outerRadius:Number, angleMin:Number, angleMax:Number)
		{
			_center = center;
			
			_innerRadius = innerRadius;
			_outerRadius = outerRadius;
			
			_innerRadiusSqr = _innerRadius * _innerRadius;
			_outerRadiusSqr = _outerRadius * _outerRadius;
			
			while (angleMax < 0) 		angleMax += twoPi;
			while (angleMax > twoPi) 	angleMax -= twoPi;
			_angleMax = angleMax;
			
			_angleLeast = _angleMax - twoPi;
			
			while (angleMin < _angleLeast) 	angleMin += twoPi;
			while (angleMin > _angleMax)	angleMin -= twoPi;
			_angleMin = angleMin;
			
			_angleSpan = _angleMax - _angleMin;
			
			area = (_outerRadiusSqr - _innerRadiusSqr) * _angleSpan * 0.5;
			
			_radiusDiff = _outerRadius - _innerRadius;
			_ratio = _innerRadius / _outerRadius;
			_ratioGap = 1 - _ratio;
		}
		
		//--------------------------------------------------------------------------
		//
		//  Methods
		//
		//--------------------------------------------------------------------------
		
		override public function contains(vector:Vector2D):Boolean 
		{ 
			var diff:Vector2D = vector.subtract(_center);
			var lengthSqr:Number = diff.lengthSqr;
			
			if(lengthSqr > _outerRadius || lengthSqr < _innerRadius) return false;
			
			var ang:Number = diff.angle;
			while (ang < _angleLeast) 	ang += twoPi;
			while (ang > _angleMax)		ang -= twoPi;
			
			return ang >= _angleMin;
		}
		
		override public function random():Vector2D 
		{ 
			var rand:Number = Math.random() * _ratioGap + _ratio;
			return Vector2D.newFromAngle(Math.random() * _angleSpan + _angleMin, _radiusDiff * rand *rand + _innerRadius).add(_center);
		}
	}
}